<template>
  <CDialog :title="title" v-model:visible="dialogVisible">
    <el-form ref="formRef" :model="formState" :rules="myRules" label-position="top">
      <el-row>
        <el-col :span="12">
          <el-form-item label="发布类型" prop="sendType" @change="radioChange">
            <el-radio-group v-model="formState.sendType">
              <el-radio label="TEXT_FILE">{{ releaseTypeEnumMap.TEXT_FILE }}</el-radio>
              <el-radio label="FILE">{{ releaseTypeEnumMap.FILE }}</el-radio>
              <el-radio label="LINK_URL">{{ releaseTypeEnumMap.LINK_URL }}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="标题" prop="title">
            <el-input v-model="formState.title" placeholder="请输入" clearable show-word-limit />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-if="formState.sendType == releaseTypeEnum.LINK_URL">
        <el-col :span="24">
          <el-form-item label="链接地址" prop="url">
            <el-input v-model="formState.url" placeholder="请输入" clearable />
          </el-form-item>
        </el-col>
      </el-row>
      <template v-if="formState.sendType == releaseTypeEnum.TEXT_FILE">
        <el-row>
          <el-col :span="12">
            <el-form-item label="副标题" prop="subtitle">
              <el-input
                v-model="formState.subtitle"
                placeholder="例：张三发布于2022年4月20日"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item
          required
          label="正文"
          class="col-content"
          :class="{ 'content-is-error': isContentEmpty }"
        >
          <GVditor
            :content="formState.content"
            ref="editorRef"
            prop-id="form-editor"
            style="width: 100%"
            @change="handleVditorChange"
            @blur="handleVditorBlur"
          ></GVditor>
          <span class="el-form-item__error" :class="{ 'item-is-error': isContentEmpty }"
            >请输入发布内容</span
          >
        </el-form-item>
      </template>
      <el-form-item
        label="附件"
        prop="files"
        v-if="formState.sendType !== releaseTypeEnum.LINK_URL"
      >
        <g-upload
          :action="uploadFilePostUrlV3"
          :postParams="{
            groupType: 'SYS_INFO_PUBLISH',
            scope: 'system',
            needRename: false
          }"
          :show-file-list="true"
          :limit="limit"
          v-model:file-list="fileList"
          @success="handleUploadSuccess"
          @remove="handleRemove"
        >
          <template #default="{ loading: btnLoading }">
            <el-button :loading="btnLoading"
              ><CIcon type="c-xian-shangchuan" class="g-mr4"></CIcon>上传文件</el-button
            >
          </template>
          <template #tip>
            <div class="g-ml10" style="display: inline-block">
              <span class="g-font-14n3">*最多上传{{ limit }}个文件，单个文件不超过20M</span>
            </div>
          </template>
        </g-upload>
      </el-form-item>
      <el-form-item label="发布时间" prop="releaseTimeType">
        <el-radio-group v-model="formState.releaseTimeType">
          <el-radio label="IMMEDIATE">立即发布</el-radio>
          <el-radio label="TIMING">定时发布</el-radio>
        </el-radio-group>
        <el-date-picker
          v-if="formState.releaseTimeType === 'TIMING'"
          class="g-ml9"
          v-model="formState.time"
          type="datetime"
          placeholder="请选择时间"
          value-format="YYYY-MM-DD HH:mm:ss"
          format="YYYY-MM-DD HH:mm:ss"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <div :class="{ 'g-flex-between-center': formState.sendType == releaseTypeEnum.TEXT_FILE }">
        <el-button
          class="preview-btn"
          size="default"
          link
          v-if="formState.sendType == releaseTypeEnum.TEXT_FILE"
          @click="previewDialogVisible = true"
          :disabled="!canPreview"
        >
          <CIcon type="c-xian-kejian" class="g-mr4"></CIcon>预览效果
        </el-button>
        <div>
          <el-button size="default" @click="dialogVisible = false">取消</el-button>
          <el-button size="default" @click="submit('DRAFT')">保存为草稿</el-button>
          <el-button size="default" type="primary" @click="handleConfirm">发布</el-button>
        </div>
      </div>
    </template>
  </CDialog>
  <Preview v-model:visible="previewDialogVisible" :info="formState"></Preview>
</template>

<script lang="ts" setup>
import { withDefaults, defineProps, defineEmits, computed, watch, reactive, ref } from 'vue';
import { CDialog } from '@/components/CDialog';
import { useMessage } from '@/hooks/useMessage';
import * as rules from './rules';
import { GUpload } from '@/components/GUpload/index';
import type { UploadFile } from 'element-plus/es/components/upload/src/upload';
import { uploadFilePostUrlV3 } from '@/apis/common/common';
import { GVditor } from '@/components/GVditor/index';
import datjs from 'dayjs';
import Preview from '@/businessComponents/Preview/index.vue';
import { getReleaseInfoDetail } from '@/apis/system/information';
import {
  moduleTypeEnum,
  moduleTypeEnumCn,
  releaseTypeEnum,
  releaseTypeEnumMap
} from '@/constants/system/systemEnum';
import { saveSystem } from '@/apis/system/information';
interface FlowDialogProps {
  visible: boolean;
  id: number | undefined;
  type: keyof typeof moduleTypeEnum;
}
const props = withDefaults(defineProps<FlowDialogProps>(), {});
const emits = defineEmits(['update:visible', 'refresh']);
const { createMessage } = useMessage();
const dialogVisible = computed({
  get: () => {
    return props.visible;
  },
  set: (value: boolean) => {
    emits('update:visible', value);
  }
});
watch(
  () => dialogVisible.value,
  val => {
    if (val) {
      init();
    } else {
      formRef.value?.resetFields();
      isContentEmpty.value = false;
    }
  }
);
const title = computed(() => {
  const str = props.id ? '编辑' : '新增';
  return str + (moduleTypeEnumCn[props.type] || '');
});
const limit = computed(() => {
  return formState.sendType == releaseTypeEnum.TEXT_FILE ? 5 : 1;
});
const isContentEmpty = ref(false); // 正文必填项校验
const previewDialogVisible = ref(false);
const editorRef = ref();
/**
 * 保存按钮
 */
function handleConfirm() {
  console.log('handleConfirm');
  formRef.value?.validate((valid: boolean) => {
    const tmpContent = formState.content.replace(/[\r\n]/g, '');
    isContentEmpty.value = !tmpContent;
    if (valid) {
      if (formState.sendType == releaseTypeEnum.TEXT_FILE) {
        tmpContent && submit('PUBLISHED');
      } else {
        submit('PUBLISHED');
      }
    }
  });
}

const submit = async (status: 'DRAFT' | 'PUBLISHED') => {
  const params = {
    id: props.id,
    module: props.type,
    sendType: formState.sendType,
    title: formState.title,
    subtitle: formState.sendType === releaseTypeEnum.TEXT_FILE ? formState.subtitle : '',
    content:
      formState.sendType === releaseTypeEnum.TEXT_FILE
        ? formState.content
        : formState.sendType === releaseTypeEnum.LINK_URL
        ? formState.url
        : '',
    files: formState.sendType !== releaseTypeEnum.LINK_URL ? formState.files : [],
    releaseTimeType: formState.releaseTimeType,
    releaseTime: formState.time,
    releaseStatus: status
  };
  try {
    await saveSystem(params);
    createMessage.success(status == 'PUBLISHED' ? '发布成功！' : '保存草稿成功！');
    dialogVisible.value = false;
    emits('refresh');
  } catch {
    console.log('error');
  }
};
// 能否预览
const canPreview = computed(() => {
  const tmpContent = formState.content.replace(/[\r\n]/g, '');
  return formState.title && formState.subtitle && tmpContent;
});
const myRules = computed(() => {
  if (formState.sendType == releaseTypeEnum.FILE) {
    return rules.rulesFiles;
  } else if (formState.sendType == releaseTypeEnum.LINK_URL) {
    return rules.rulesUrl;
  } else {
    return rules.rulesFilesText;
  }
});
function handleVditorChange(val: string) {
  formState.content = val;
  const tmpContent = formState.content.replace(/[\r\n]/g, '');
  if (tmpContent) {
    isContentEmpty.value = false;
  } else {
    isContentEmpty.value = true;
  }
}
function handleVditorBlur() {
  const tmpContent = formState.content.replace(/[\r\n]/g, '');
  if (tmpContent) {
    isContentEmpty.value = false;
  } else {
    isContentEmpty.value = true;
  }
}

const formRef = ref();
const loading = ref(false);
const fileList = ref([] as any[]);
const radioChange = () => {
  formRef.value?.clearValidate('url');
  formRef.value?.clearValidate('title');
  formRef.value?.clearValidate('files');
};
/**
 * 表单内容
 */
const formState = reactive({
  sendType: 'TEXT_FILE' as keyof typeof releaseTypeEnum,
  title: '',
  subtitle: '',
  content: '',
  url: '',
  files: [] as any[],
  time: datjs().format('YYYY-MM-DD HH:mm:ss'),
  releaseTimeType: 'IMMEDIATE' as 'IMMEDIATE' | 'TIMING'
});

/**
 * 初始化
 */

async function init() {
  if (props.id) {
    loading.value = true;
    try {
      const info = await getReleaseInfoDetail(Number(props.id));
      formState.sendType = info.sendType;
      formState.title = info.title;
      formState.content = info.content;
      formState.subtitle = info.subtitle;
      editorRef.value?.setEditValue(info.content);
      formState.files = info.files;
      formState.releaseTimeType = info.releaseTimeType;
      formState.url = info.sendType == 'LINK_URL' ? info.content : '';
      fileList.value = [];
      if (info.files && info.files.length) {
        for (let obj of info.files) {
          fileList.value.push({
            url: obj.fileUrl,
            name: obj.fileName
          });
        }
      }
    } finally {
      loading.value = false;
    }
  } else {
    fileList.value = [];
    formState.sendType = 'TEXT_FILE';
    formState.title = '';
    formState.subtitle = '';
    formState.content = '';
    formState.url = '';
    formState.files = [];
    formState.time = datjs().format('YYYY-MM-DD HH:mm:ss');
    formState.releaseTimeType = 'IMMEDIATE';
  }
}

const handleUploadSuccess = (file: any) => {
  if (file.response.msg == '成功') {
    formState.files.push({
      fileUrl: file.response.data.fileUrl,
      fileName: file.name
    });
    createMessage.success('上传成功');
    formRef.value?.clearValidate('files');
  } else {
    createMessage.info('上传失败');
  }
};

function handleRemove(file: UploadFile, files: any[]) {
  const { status, uid } = file;
  if (status === 'success') {
    formState.files = [];
    for (let obj of files) {
      formState.files.push({
        fileName: obj.name,
        fileUrl: obj.url || obj.response?.data.fileUrl
      });
    }
  }
}
</script>

<style lang="scss" scoped>
.el-form-item__error {
  position: absolute;
  left: 0;
  width: 100%;
  opacity: 0;
  transform: translateY(-5px);
  transition: opacity 0.5s, transform 0.5s;
}
.content-is-error {
  :deep(.vditor) {
    border: 1px solid var(--el-color-danger);
  }
}
.el-form-item__error.item-is-error {
  opacity: 1;
  transform: translateY(0);
}

.preview-btn.is-disabled {
  background: none !important;
}
</style>

<style lang="scss">
#form-editor.vditor {
  &.vditor--fullscreen {
    .vditor-toolbar.vditor-toolbar--pin {
      top: auto;
    }
  }
  &:not(.vditor--fullscreen) {
    .vditor-toolbar.vditor-toolbar--pin {
      padding-left: 20px !important;
    }
    .vditor-reset {
      padding: 10px 20px !important;
    }
  }
}
</style>
